package org.example.learn.javassist.method;

import javassist.*;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class GenerateClassMethodField {

    public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        // 对象池
        ClassPool pool = ClassPool.getDefault();

        // 创建类
        CtClass ctClass = pool.makeClass("org.example.learn.javassist.method.MathUtil");

        // 属性字段
        CtField ctField = new CtField(CtClass.doubleType,"π",ctClass);
        ctField.setModifiers(Modifier.PRIVATE + Modifier.STATIC + Modifier.FINAL);
        ctClass.addField(ctField,"3.1415926");

        // 创建方法：计算圆面积
        CtMethod calculateCircularArea = new CtMethod(CtClass.doubleType,"calculateCircularArea",new CtClass[]{CtClass.doubleType},ctClass);
        calculateCircularArea.setModifiers(Modifier.PUBLIC);
        calculateCircularArea.setBody("{return π * $1 * $1;}");
        ctClass.addMethod(calculateCircularArea);

        // 创建方法：计算两数之和
        CtMethod sumOfTwoNumbers = new CtMethod(pool.get(Double.class.getName()),"sumOfTwoNumbers",new CtClass[]{CtClass.doubleType,CtClass.doubleType},ctClass);
        sumOfTwoNumbers.setModifiers(Modifier.PUBLIC);
        sumOfTwoNumbers.setBody("{return Double.valueOf($1 + $2);}");
        ctClass.addMethod(sumOfTwoNumbers);

        // 输出类内容
        ctClass.writeFile();

        Class<?> clazz = ctClass.toClass();
        Object object = clazz.newInstance();

        Method mCalculateCircularArea = clazz.getDeclaredMethod("calculateCircularArea",double.class);
        Object val1 = mCalculateCircularArea.invoke(object,1.45);
        System.out.println("圆面积：" + val1);

        Method mSumOfTwoNumbers = clazz.getDeclaredMethod("sumOfTwoNumbers",double.class,double.class);
        Object val2 = mSumOfTwoNumbers.invoke(object,10,11);
        System.out.println("两数和：" + val2);
    }
}
